package simax.integrator.test

import java.util.Map;

class UniquePairGenerator {
	
	/**
	 * http://groovy.codehaus.org/Test+Combinations
	 * @param partialCombinations
	 * @param inputsLeft
	 * @return
	 */
	def results = new HashSet()
	def usedPairs = new HashSet()
	
	def pairs(Map partialCombinations, inputsLeft) {
		def first = getFirstEntry(inputsLeft)
		def partialResults = [ ]
		first.value.each{
			def next = [(first.key):it]
			def nextEntry = getFirstEntry(next)
			next.putAll(partialCombinations)
			partialResults << next
		}
		if (inputsLeft.size() == 1) {
			partialResults.each {
				if (!containsUsedPairs(it)) {
					updateUsedPairs(it)
					results << it
				}
			}
		} else {
			partialResults.each{
				def rest = inputsLeft.clone()
				rest.remove(first.key)
				pairs(it, rest)
			}
		}
		return results
	}
	
	
	def getFirstEntry(map) {
		return map.entrySet().toList().get(0)
	}
	
	def getAllPairsFromMap(map) {
		if (map.size() <= 1) return null
		def allPairs = new HashSet()
		def first = getFirstEntry(map)
		def rest = map.clone()
		rest.remove(first.key)
		rest.each{
			def nextPair = new HashSet()
			nextPair << first
			nextPair << it
			allPairs << nextPair
		}
		def restPairs = getAllPairsFromMap(rest)
		if (restPairs != null) {
			allPairs.addAll(restPairs)
		}
		return allPairs
	}
	
	boolean containsUsedPairs(map) {
		if (map.size() <= 1) return false
		def unpaired = true
		getAllPairsFromMap(map).each {
			if (unpaired) {
				if (usedPairs.contains(it)) unpaired = false
			}
		}
		return !unpaired
	}
	
	def updateUsedPairs(map) {
		getAllPairsFromMap(map).each{ usedPairs << it }
	}
	
}
